#!/usr/bin/php
<?php
require_once dirname(__FILE__) . '/../../lib/facebook-php-sdk/src/facebook.php';
require_once 'log4php/Logger.php';
require_once 'utils.php';
require_once 'db.php';
require_once 'error.php';
require_once 'ex.php';

/*******************************************************
 *					SOME CONSTANT VALUES
 * ****************************************************/
define('QUERY_LIMIT', 100);				//max number of results for a Query

define('DEFAULT_CRON_DATE', 1314835200); 	//profile information prior to this date will not be kept by the job.
//Human time (GMT): Thu, 01 Sep 2011 00:00:00 GMT
//Human time (your time zone): Thu 01 Sep 2011 02:00:00 AM CEST

//init file logger
$loggerConfig =array(
		'appenders' => array(
			'cronLog' => array(
				'class' => 'LoggerAppenderFile',
				'layout' => array(
					'class' => 'LoggerLayoutTTCC',
					),
				'params' => array(
					'file' => dirname(__FILE__) .'/log',
					'append' => true
					),
				),
			),
		'rootLogger' => array(
			'appenders' => array('cronLog'),
			),
		);	
Logger::configure($loggerConfig);
$log = Logger::getLogger('cron');

$today = date('Y-m-d H:i:s');
$log->info('executing cron ' . $today );

$error;

//init Facebook
$fb = new Facebook(array(
			'appId' => getFBAppID(),
			'secret' => getFBAppSecret(),
			));

//			solo per debug rimuovere!!!! //
//
//DBManager::clear();
//
//			solo per debug rimuovere!!!! //


//retrieves long life token from the DB
$stmtTokens = DBManager::statementQueryTokens();
if(!$stmtTokens->execute()){
	$error = new Error('Impossibile recuperare token.', 'cron');
	$error->report();
	die();
}

$rows = $stmtTokens->fetchAll();

//foreach token(=user) dump the profile information
foreach($rows as $row){
	$token = $row['token'];
	$id = $row['id'];

	//last cron executed on this user
	$lastCron = $row['lastCronUpdate'];

	$log->info('-- Updating user ' . $id . ' --');

	if($lastCron == 0){ //first time that we run the job on the user
		$lastCron = DEFAULT_CRON_DATE;
		$log->info('-- first time for this user --');
	}
	else
		$log->info('-- last cron update done by ' . date('Y-m-d H:i:s', $lastCron));

	//set access token to authorize our requests
	$fb->setAccessToken($token);


	/********************************************************
	 *                     DUMPING OUTBOXES
	 ********************************************************/
	dumpOutboxes($id, $lastCron);

	/********************************************************
	 *                     DUMPING HOMES
	 ********************************************************/
	dumpHomes($id, $lastCron);

	/********************************************************
	 *                     DUMPING FRIENDS
	 ********************************************************/
	dumpFriends($id, $lastCron);

	/********************************************************
	 *                     DUMPING FEEDS
	 ********************************************************/
	dumpFeeds($id, $lastCron);

	/********************************************************
	 *                   DUMPING STATUSES
	 ********************************************************/
	dumpStatuses($id, $lastCron);

	/********************************************************
	 *                UPDATING LAST CRON
	 ********************************************************/
	updateLastCron($id, $today);

	$log->info('-- Update done for user ' . $id . ' --');
}

$stmtTokens->closeCursor();


$log->info('cron finished at ' . date('Y-m-d H:i:s'));



/********************************************************
 *                UPDATING LAST CRON
 * @param id id facebook dell'utente a cui aggiornare l'ultimo
 *	salvataggio dei dati
 * @param update la data a cui impostare l'ultimo salvataggio
 ********************************************************/
function updateLastCron($id, $update){
	global $log;
	$log->info('--- UPDATING LAST CRON ---');
	$stmtUpdateLastCron = DBManager::statementUpdateLastCron();
	try {
		$stmtUpdateLastCron->bindValue(':id', $id, PDO::PARAM_STR);
		$stmtUpdateLastCron->bindValue(':update', $update, PDO::PARAM_STR);
		$stmtUpdateLastCron->execute();
	} catch (PDOException $e){
		$error = new Error(
				$e->getMessage(),
				'updating last cron[cron.php]',
				$id,
				Error::LVL_FATAL
				);
		$error->report();
	}
	$stmtUpdateLastCron->closeCursor();
}


/********************************************************
 *                      DUMP FRIENDS
 * Salva tutti i friend dell'utente aggiunti dall'ultimo 
 * salvataggio effettuato con il cron
 * @param id l'id facebook dell'utente 
 * @param lastCron unix time stamp dell'utimo cron effettuato
 ********************************************************/
function dumpFriends($id, $lastCron){
	global $log;
	global $fb;

	$log->info('--- DUMPING FRIENDS ---');
	try {
		$friends = $fb->api('/me?fields=friends.fields(id)','GET');
	} catch(Exception $e){
		$error = new Error(
				$e->getMessage(),
				'Facebook raises this exception while cron is requesting friends [cron.php]',
				$id,
				Error::LVL_ERROR
				);
		$error->report();
		return;
	}

	if(!array_key_exists('friends', $friends) || !array_key_exists('data', $friends['friends']))
		return;

	$stmtFriends = DBManager::statementInsertFriend();
	foreach($friends['friends']['data'] as $friend){
		try {
			if(DBManager::existFriendRelation($id, $friend['id']))
				continue;

			DBManager::beginTransaction();
			if(!DBManager::existUser($friend['id'])){
				$log->info('dump public profile from friend[id]');
				dumpUserPublicProfile($friend['id']);
			}

			$stmtFriends->bindValue(':uid', $id, PDO::PARAM_STR);
			$stmtFriends->bindValue(':fid', $friend['id'], PDO::PARAM_STR);

			$stmtFriends->execute();
			DBManager::commitTransaction();
		} catch (PDOException $e){
			DBManager::rollBack();
			$error = new Error(
					$e->getMessage(),
					'postFriends[cron.php]',
					$id,
					Error::LVL_ERROR
					);
			$error->report();
		}
	}
	$stmtFriends->closeCursor();
}


/********************************************************
 *                      DUMP OUTBOXES
 * Salva i messaggi privati dell'utente spediti dopo 
 * l'ultimo salvataggio effettuato con il cron
 * @param id l'id facebook dell'utente 
 * @param lastCron unix time stamp dell'utimo cron effettuato
 ********************************************************/
function dumpOutboxes($id, $lastCron){
	global $log;
	global $fb;

	$log->info('--- DUMPING OUTBOXES ---');
	try {
		$request = 'me?fields=outbox.since('. $lastCron .').limit('. QUERY_LIMIT .').fields(from,id,message,unread,to,unseen,updated_time,comments.fields(message,id,from,created_time))';
		$outboxes = $fb->api($request, 'GET');

	} catch(Exception $e){
		$error = new Error(
				$e->getMessage(),
				'Facebook raises this exception while cron is requesting outboxes. Request : ' . $request,
				$id,
				Error::LVL_ERROR
				);
		$error->report();
		return;
	}
	if(!array_key_exists('outbox', $outboxes) || !array_key_exists('data', $outboxes['outbox']))
		return;

	$stmt = DBManager::statementInsertOutboxes();
	$stmt->bindValue(':idUser', $id, PDO::PARAM_STR);
	foreach($outboxes['outbox']['data'] as $value){
		try {
			if(DBManager::existsObj($value['id'])) { //for some reason the object has been already dumped
				$log->info('for some reason the object has been already dumped');
				continue;
			}
			DBManager::beginTransaction();

			//$log->info($value);

			//First of all adds an object for the home
			DBManager::insertObj($value['id'], 'home');

			if(array_key_exists('to', $value)){
				$log->info('!!!!! dumping outboxes tos');
				dumpTo($value['to'], $value['id']);
				$log->info('!!!!! dumping outboxes tos finished');
}
			
			if(array_key_exists('from', $value)){
				$log->info('£££££ dumping outboxes from');
				dumpFrom($value['from'], $value['id']);
				$log->info('£££££ dumping outboxes from finished');
}
			//dumps all the comments
			if(array_key_exists('comments', $value) && array_key_exists('data', $value['comments'])){
				$log->info('%%%%%%%% dumping outboxes comments');
				dumpComments($value['id'], $value['comments']['data']);
				$log->info('%%%%%%%% dumping outboxes comments finished');
}
				$log->info('dumping outbox');
			$stmt->bindValue(':id', $value['id'], PDO::PARAM_STR);

			if(!array_key_exists('updated_time', $value))
				$stmt->bindValue(':updated_time', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':updated_time', $value['updated_time'], PDO::PARAM_INT);

			if(!array_key_exists('message', $value))
				$stmt->bindValue(':message', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':message', $value['message'], PDO::PARAM_STR);

			$stmt->execute();
			$stmt->closeCursor();
			DBManager::commitTransaction();

		} catch (PDOException $e){
			DBManager::rollBack();
			$log->info('error in outboxes');

//			$stmt->debugDumpParams();
			$log->error($e->getMessage());
			$error = new Error(
					$e->getMessage(),
					'post outbox[cron.php]',
					$id,
					Error::LVL_ERROR
					);
			$error->report();
		}


	}
}

/********************************************************
 *                      DUMP HOMES
 * Salva i contenuti della home dell'utente creati dopo 
 * l'ultimo salvataggio effettuato con il cron
 * @param id l'id facebook dell'utente 
 * @param lastCron unix time stamp dell'utimo cron effettuato
 ********************************************************/
function dumpHomes($id, $lastCron){
	global $log;
	global $fb;

	$log->info('--- DUMPING HOMES ---');
	try {
		$request = 'me?fields=home.since('. $lastCron .').limit('. QUERY_LIMIT .').fields(caption,created_time,description,from,id,link,message_tags,message,object_id,is_published,name,picture,source,story,story_tags,to,type,via,comments,likes)';
		$homes = $fb->api($request, 'GET');

	} catch(Exception $e){
		$error = new Error(
				$e->getMessage(),
				'Facebook raises this exception while cron is requesting homes. Request : ' . $request,
				$id,
				Error::LVL_ERROR
				);
		$error->report();
		return;
	}
	if(!array_key_exists('home', $homes) || !array_key_exists('data', $homes['home']))
		return;

	$stmt = DBManager::statementInsertHome();
	$stmt->bindValue(':idUser', $id, PDO::PARAM_STR);
	foreach($homes['home']['data'] as $home){
		try {
			if(DBManager::existsObj($home['id'])) { //for some reason the object has been already dumped
				$log->info('for some reason the object has been already dumped');
				continue;
			}
			DBManager::beginTransaction();

			//First of all adds an object for the home
			DBManager::insertObj($home['id'], 'home');


			if(array_key_exists('message_tags', $home)){
				$log->info('homes message tag');
				dumpMessageTags($home['message_tags'], $home['id'], $id);	
			}
			if(array_key_exists('story_tags', $home)){
				$log->info('homes story tag');
				dumpStoryTags($home['story_tags'], $home['id'], $id);	
			}
			if(array_key_exists('to', $home)){
				$log->info('homes to');
				dumpTo($home['to'], $home['id']);
			}

			if(array_key_exists('from', $home))
				dumpFrom($home['from'], $home['id']);

			if(array_key_exists('via', $home))
				dumpVia($home['via'], $home['id']);

			$stmt->bindValue(':id', $home['id'], PDO::PARAM_STR);

			//dumps all the comments
			if(array_key_exists('comments', $home))
				dumpComments($home['id'], $home['comments']['data']);

			//dumps like realted to the object
			if(array_key_exists('likes', $home))
				dumpLikes($home['id'], $home['likes']['data']);
			 
			if(!array_key_exists('caption', $home))
				$stmt->bindValue(':caption', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':caption', $home['caption'], PDO::PARAM_STR);

			if(!array_key_exists('created_time', $home))
				$stmt->bindValue(':created_time', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':created_time', $home['created_time'], PDO::PARAM_INT);

			if(!array_key_exists('description', $home))
				$stmt->bindValue(':description', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':description', $home['description'], PDO::PARAM_STR);


			if(!array_key_exists('is_published', $home))
				$stmt->bindValue(':is_published', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':is_published', $home['is_published'], PDO::PARAM_INT);

			if(!array_key_exists('link', $home))
				$stmt->bindValue(':link', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':link', $home['link'], PDO::PARAM_STR);

			if(!array_key_exists('message', $home))
				$stmt->bindValue(':message', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':message', $home['message'], PDO::PARAM_STR);

			if(!array_key_exists('name', $home))
				$stmt->bindValue(':name', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':name', $home['name'], PDO::PARAM_STR);

			if(!array_key_exists('object_id', $home))
				$stmt->bindValue(':object_id', NULL, PDO::PARAM_STR);
			else {
				if(!DBManager::existsObj($home['object_id']))
					DBManager::insertObj($home['object_id'], $home['type']);
				$stmt->bindValue(':object_id', $home['object_id'], PDO::PARAM_STR);
			}

			if(!array_key_exists('parent_id', $home))
				$stmt->bindValue(':parent_id', NULL, PDO::PARAM_STR);
			else{
				if(!DBManager::existsObj($home['parent_id']))
					DBManager::insertObj($home['parent_id'], $home['type']);

				$stmt->bindValue(':parent_id', $home['parent_id'], PDO::PARAM_STR);
			}	

			if(!array_key_exists('source', $home))
				$stmt->bindValue(':source', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':source', $home['source'], PDO::PARAM_STR);

			if(!array_key_exists('type', $home))
				$stmt->bindValue(':type', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':type', $home['type'], PDO::PARAM_STR);

			if(!array_key_exists('story', $home))
				$stmt->bindValue(':story', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':story', $home['story'], PDO::PARAM_STR);


			$stmt->execute();
			$stmt->closeCursor();
			DBManager::commitTransaction();

		} catch (PDOException $e){
			DBManager::rollBack();
			$log->info('error in homes');

			$stmt->debugDumpParams();
			$log->error($e->getMessage());
			$error = new Error(
					$e->getMessage(),
					'post home[cron.php]',
					$id,
					Error::LVL_ERROR
					);
			$error->report();
		}


	}
}


/********************************************************
 *                      DUMP FEEDS
 * Salva tutti i feed dell'utente creati dall'ultimo 
 * salvataggio effettuato con il cron
 * @param id l'id facebook dell'utente 
 * @param lastCron unix time stamp dell'utimo cron effettuato
 ********************************************************/
function dumpFeeds($id, $lastCron){
	global $log;
	global $fb;

	$log->info('--- DUMPING FEEDS ---');
	try {
		$request = 'me?fields=feed.since('. $lastCron .').limit('. QUERY_LIMIT .').fields(caption,comments.fields(message,id,from,created_time,user_likes,likes.fields(id)),coordinates,created_time,description,feed_targeting,from,id,is_published,likes.fields(id),link,message,message_tags,name,object_id,parent_id,place,source,type,status_type,story,story_tags,to,timeline_visibility,via)';
		$feeds = $fb->api($request, 'GET');

	} catch(Exception $e){
		$error = new Error(
				$e->getMessage(),
				'Facebook raises this exception while cron is requesting feeds. Request : ' . $request,
				$id,
				Error::LVL_ERROR
				);
		$error->report();
		return;
	}
	if(!array_key_exists('feed', $feeds) || !array_key_exists('data', $feeds['feed']))
		return;

	$stmtFeed = DBManager::statementInsertFeed();
	$stmtFeed->bindValue(':idUser', $id, PDO::PARAM_STR);
	foreach($feeds['feed']['data'] as $feed){
		try {
			if(DBManager::existsObj($feed['id'])) { //for some reason the object has been already dumped
				$log->info('for some reason the object has been already dumped');
				continue;
			}

			DBManager::beginTransaction();

			//first of all we add an object
			DBManager::insertObj($feed['id'], 'feed');

			if(array_key_exists('from', $feed))
				dumpFrom($feed['from'], $feed['id']);

			if(array_key_exists('via', $feed))
				dumpVia($feed['via'], $feed['id']);

			//dumps all the comments
			if(array_key_exists('comments', $feed))
				dumpComments($feed['id'], $feed['comments']['data']);

			//dumps like realted to the object
			if(array_key_exists('likes', $feed))
				dumpLikes($feed['id'], $feed['likes']['data']);

			$stmtFeed->bindValue(':id', $feed['id'], PDO::PARAM_STR);

			if(!array_key_exists('caption', $feed))
				$stmtFeed->bindValue(':caption', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':caption', $feed['caption'], PDO::PARAM_STR);

			if(!array_key_exists('coordinates', $feed))
				$stmtFeed->bindValue(':coordinates', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':coordinates', $feed['coordinates'], PDO::PARAM_STR);

			if(!array_key_exists('created_time', $feed))
				$stmtFeed->bindValue(':created_time', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':created_time', $feed['created_time'], PDO::PARAM_INT);

			if(!array_key_exists('description', $feed))
				$stmtFeed->bindValue(':description', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':description', $feed['description'], PDO::PARAM_STR);

			if(!array_key_exists('feed_targeting', $feed))
				$stmtFeed->bindValue(':feed_targeting', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':feed_targeting', $feed['feed_targeting'], PDO::PARAM_STR);

			if(!array_key_exists('is_published', $feed))
				$stmtFeed->bindValue(':is_published', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':is_published', $feed['is_published'], PDO::PARAM_INT);

			if(!array_key_exists('link', $feed))
				$stmtFeed->bindValue(':link', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':link', $feed['link'], PDO::PARAM_STR);

			if(!array_key_exists('message', $feed))
				$stmtFeed->bindValue(':message', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':message', $feed['message'], PDO::PARAM_STR);

			if(array_key_exists('message_tags', $feed))
				dumpMessageTags($feed['message_tags'], $feed['id'], $id);	

			if(!array_key_exists('name', $feed))
				$stmtFeed->bindValue(':name', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':name', $feed['name'], PDO::PARAM_STR);

			if(!array_key_exists('object_id', $feed))
				$stmtFeed->bindValue(':object_id', NULL, PDO::PARAM_STR);
			else {
				if(!DBManager::existsObj($feed['object_id']))
					DBManager::insertObj($feed['object_id'], $feed['type']);
				$stmtFeed->bindValue(':object_id', $feed['object_id'], PDO::PARAM_STR);
			}

			if(!array_key_exists('parent_id', $feed))
				$stmtFeed->bindValue(':parent_id', NULL, PDO::PARAM_STR);
			else{
				if(!DBManager::existsObj($feed['parent_id']))
					DBManager::insertObj($feed['parent_id'], $feed['type']);

				$stmtFeed->bindValue(':parent_id', $feed['parent_id'], PDO::PARAM_STR);
			}	

			if(!array_key_exists('place', $feed))
				$stmtFeed->bindValue(':place', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':place', $feed['place']['id'], PDO::PARAM_STR);				//TODO deve essere salvato in qualche altro modo?

			if(!array_key_exists('source', $feed))
				$stmtFeed->bindValue(':source', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':source', $feed['source'], PDO::PARAM_STR);

			if(!array_key_exists('type', $feed))
				$stmtFeed->bindValue(':type', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':type', $feed['type'], PDO::PARAM_STR);

			if(!array_key_exists('status_type', $feed))
				$stmtFeed->bindValue(':status_type', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':status_type', $feed['status_type'], PDO::PARAM_STR);

			if(!array_key_exists('story', $feed))
				$stmtFeed->bindValue(':story', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':story', $feed['story'], PDO::PARAM_STR);

			if(array_key_exists('story_tags', $feed))
				dumpStoryTags($feed['story_tags'], $feed['id'], $id);	

			if(array_key_exists('to', $feed))
				dumpTo($feed['to'], $feed['id']);

			if(!array_key_exists('timeline_visibility', $feed))
				$stmtFeed->bindValue(':timeline_visibility', NULL, PDO::PARAM_STR);
			else
				$stmtFeed->bindValue(':timeline_visibility', $feed['timeline_visibility'], PDO::PARAM_STR);


			$stmtFeed->execute();
			$stmtFeed->closeCursor();
			DBManager::commitTransaction();

		} catch (PDOException $e){
			DBManager::rollBack();
			//			$log->error($e->getMessage());
			$error = new Error(
					$e->getMessage(),
					'postFeed[cron.php]',
					$id,
					Error::LVL_ERROR
					);
			$error->report();
		}
	}
}


/********************************************************
 *                      DUMP STATUSES
 * Salva tutti gli status dell'utente creati dall'ultimo 
 * salvataggio effettuato con il cron
 * @param id l'id facebook dell'utente 
 * @param lastCron unix time stamp dell'utimo cron effettuato
 ********************************************************/
function dumpStatuses($id, $lastCron){
	global $log;
	global $fb;
	$log->info('--- DUMPING STATUSES ---');
	try {
		$request = 'me?fields=statuses.since('. $lastCron .').limit('. QUERY_LIMIT .').fields(id,from,message,comments.fields(message,id,from,created_time,user_likes,likes.fields(id)),likes.fields(id))';
		$statuses = $fb->api($request, 'GET');

	} catch(Exception $e){
		$error = new Error(
				$e->getMessage(),
				'Facebook raises this exception while cron is requesting statuses. Request : ' . $request,
				$id,
				Error::LVL_ERROR
				);
		$error->report();
		return;
	}

	if(!array_key_exists('statuses', $statuses) || !array_key_exists('data', $statuses['statuses']))
		return;

	//	var_dump($statuses);

	$stmtStatus = DBManager::statementInsertStatus();
	foreach($statuses['statuses']['data'] as $status){
		try {

			$userId = $status['from']['id'];
			if(DBManager::existsObj($status['id'])) { //for some reason the object has been already dumped
				$log->info('for some reason the object has been already dumped');
				continue;
			}

			DBManager::beginTransaction();

			//adds a new status object for cross correlation
			DBManager::insertObj($status['id'], 'status');

			//adds a new user if not exist
			if(!DBManager::existUser($userId)){
				$log->info('dump public profile from status');
				dumpUserPublicProfile($userId);
			}

			//dumps comments related to the object
			if(array_key_exists('comments', $status))
				dumpComments($status['id'], $status['comments']['data']);

			//dumps like realted to the object
			if(array_key_exists('likes', $status))
				dumpLikes($status['id'], $status['likes']['data']);

			$message = array_key_exists('message', $status) ? $status['message'] : NULL;

			$stmtStatus->bindValue(':id', $status['id'], PDO::PARAM_STR);
			$stmtStatus->bindValue(':from', $userId, PDO::PARAM_STR);
			$stmtStatus->bindValue(':message', $message, PDO::PARAM_STR);

			$stmtStatus->execute();
			DBManager::commitTransaction();
		} catch (PDOException $e){
			DBManager::rollBack();
			$error = new Error(
					$e->getMessage(),
					'postStatus[cron.php]',
					$id,
					Error::LVL_ERROR
					);
			$error->report();
		}
	}
	$stmtStatus->closeCursor();
}

/**
 * Salva tutti i commenti relativi ad una entità FB nel DB e mette in relazione questi mess .
 * @param obj id dell'elemento soggetto dei commenti
 * @param comments array di array associativi contenenti messaggi
 * @throws PDOException se l'inserimento fallisce.
 */
function dumpComments($obj, $comments){
	$stmt = DBManager::statementInsertComments();

	global $log;

	$stmt->bindValue(':refer', $obj, PDO::PARAM_STR);
	foreach($comments as $comment){
		if(array_key_exists('id', $comment) && DBManager::existsObj($comment['id']))
			continue;
		
		$log->info('add a new obj for the comment');	
		DBManager::insertObj($comment['id'], 'comment');
		$stmt->bindValue(':id', $comment['id'], PDO::PARAM_STR);

		//dumps like realted to the object
		if(array_key_exists('likes', $comment))
			dumpLikes($comment['id'], $comment['likes']['data']);

		if(array_key_exists('from', $comment)){
			dumpFrom($comment['from'], $comment['id']);

			if(array_key_exists('message_tags', $comment)){
				$log->info('comment message tag');
				dumpMessageTags($comment['message_tags'], $comment['id'], $comment['from']['id']);
			}
		} 
		
		if(array_key_exists('message', $comment))
			$stmt->bindValue(':message', $comment['message'], PDO::PARAM_STR);
		else
			$stmt->bindValue(':message', NULL, PDO::PARAM_STR);

		if(array_key_exists('user_likes', $comment))
			$stmt->bindValue(':user_likes', $comment['user_likes'], PDO::PARAM_INT);
		else
			$stmt->bindValue(':user_likes', 0, PDO::PARAM_INT);

		if(array_key_exists('created_time', $comment))
			$stmt->bindValue(':created_time', $comment['created_time'], PDO::PARAM_STR);
		else
			$stmt->bindValue(':created_time', 0, PDO::PARAM_INT);

		$stmt->execute();
		$stmt->closeCursor();
	}
}

/**
 * Salva tutti i likes relativi ad una entità FB nel DB.
 * @param obj id dell'elemento soggetto del like
 * @param likes array di id utenti che hanno espresso un like per l'oggetto
 * @throws PDOException se l'inserimento fallisce.
 */
function dumpLikes($obj, $likes){
	$stmt = DBManager::statementInsertLike();

	global $log;
	try {
		//		echo 'likes';
		$stmt->bindValue(':what', $obj, PDO::PARAM_STR);
		foreach($likes as $like){
			//			var_dump($like);
			if(!DBManager::existUser($like['id'])){
				$log->info('dump public profile from like[id]');
				dumpUserPublicProfile($like['id']);
			}
			$stmt->bindValue(':idUser', $like['id'], PDO::PARAM_STR);
			$stmt->execute();
		}
	}
	catch(PDOException $e){
		$error = new Error(
				$e->getMessage(),
				'postLike[cron.php]',
				$obj,
				Error::LVL_ERROR
				);
		$error->report();
		throw $e;
	}

	$stmt->closeCursor();
}


function dumpStoryTags($tags, $refer, $from){
	$stmt = DBManager::statementInsertStoryTags();
	global $log;
	//var_dump($tags);
	try {
		//binds values generic for all tag
		$stmt->bindValue(':refer', $refer, PDO::PARAM_STR);
		$stmt->bindValue(':from', $from, PDO::PARAM_STR);

		foreach($tags as $key => $value){
			foreach($value as $tag){
				if(!array_key_exists('type', $tag))
					continue;

				if((strcmp($tag['type'], 'user') == 0) && !DBManager::existUser($tag['id'])){
					$log->info('dump public profile from storytags[id]');
					dumpUserPublicProfile($tag['id']);
				}
				$stmt->bindValue(':tagged', $tag['id'], PDO::PARAM_STR);
				$stmt->bindValue(':offset', $tag['offset'], PDO::PARAM_INT);
				$stmt->bindValue(':length', $tag['length'], PDO::PARAM_INT);
				$stmt->bindValue(':type', $tag['type'], PDO::PARAM_STR);

				$stmt->execute();
			}
		}
	}
	catch(PDOException $e){
		$error = new Error(
				$e->getMessage(),
				'dumping message tags[cron.php]',
				$from,
				Error::LVL_ERROR
				);
		$error->report();
		throw $e;
	}

	$stmt->closeCursor();
}

function dumpMessageTags($tags, $refer, $from){
	$stmt = DBManager::statementInsertMessageTags();
	global $log;

	try {
		//binds values generic for all tag
		$stmt->bindValue(':refer', $refer, PDO::PARAM_STR);
		$stmt->bindValue(':from', $from, PDO::PARAM_STR);

		foreach($tags as $key => $value){
			foreach($value as $tag){
				if(!array_key_exists('type', $tag))
					continue;

				if((strcmp($tag['type'], 'user') == 0) && !DBManager::existUser($tag['id'])){
					$log->info('dump public profile from messagetag[id]');
					dumpUserPublicProfile($tag['id']);
				}

				$stmt->bindValue(':tagged', $tag['id'], PDO::PARAM_STR);
				$stmt->bindValue(':offset', $tag['offset'], PDO::PARAM_INT);
				$stmt->bindValue(':length', $tag['length'], PDO::PARAM_INT);
				$stmt->bindValue(':type', $tag['type'], PDO::PARAM_STR);

				$stmt->execute();
			}
		}
	}
	catch(PDOException $e){
		$error = new Error(
				$e->getMessage(),
				'dumping message tags[cron.php]',
				$from,
				Error::LVL_ERROR
				);
		$error->report();
		throw $e;
	}

	$stmt->closeCursor();
}

function dumpVia($via, $refer){
	$stmt = DBManager::statementInsertVia();
	global $log;

	try {
		//binds values generic for all to
		$stmt->bindValue(':refer', $refer, PDO::PARAM_STR);

		if(!array_key_exists('category', $via)){
			$log->info('to user '. $via['id']);
			if(!DBManager::existUser($via['id'])){

				$log->info('dump public profile from via[id]');
				dumpUserPublicProfile($via['id']);
			}
			$stmt->bindValue(':category', 'user', PDO::PARAM_STR);
		}
		else{

			$log->info('via category '. $via['category']);
			$stmt->bindValue(':category', $via['category'], PDO::PARAM_STR);
		}

		$stmt->bindValue(':via', $via['id'], PDO::PARAM_STR);
		if(!array_key_exists('name', $via))
			$stmt->bindValue(':name', NULL, PDO::PARAM_STR);
		else
			$stmt->bindValue(':name', $via['name'], PDO::PARAM_STR);

		$stmt->execute();
	}
	catch(PDOException $e){
		$error = new Error(
				$e->getMessage(),
				'dumping tos[cron.php]',
				$refer,
				Error::LVL_ERROR
				);
		$error->report();
		throw $e;
	}

	$log->info('via finished');
	$stmt->closeCursor();
}

function dumpFrom($from, $refer){
	$stmt = DBManager::statementInsertFrom();
	global $log;

	if(!array_key_exists('id', $from)){
		$log->info('from non ha alcun id: \n' .$from);
		return;
}
		

	try {
		//binds values generic for all
		$stmt->bindValue(':refer', $refer, PDO::PARAM_STR);

		if(!array_key_exists('category', $from)){
			$log->info('from user '. $from['id']);
			if(!DBManager::existUser($from['id'])){
				$log->info('dump public profile from from[id]');
				dumpUserPublicProfile($from['id']);
			}
			$stmt->bindValue(':category', 'user', PDO::PARAM_STR);
		}
		else{

			$log->info('from category '. $from['category']);
			$stmt->bindValue(':category', $from['category'], PDO::PARAM_STR);
		}

		$stmt->bindValue(':from', $from['id'], PDO::PARAM_STR);
		if(!array_key_exists('name', $from))
			$stmt->bindValue(':name', NULL, PDO::PARAM_STR);
		else
			$stmt->bindValue(':name', $from['name'], PDO::PARAM_STR);

		$stmt->execute();
	}
	catch(PDOException $e){
		$error = new Error(
				$e->getMessage(),
				'dumping tos[cron.php]',
				$refer,
				Error::LVL_ERROR
				);
		$error->report();
		throw $e;
	}

	$log->info('from finished');
	$stmt->closeCursor();
}

function dumpTo($tos, $refer){
	$stmt = DBManager::statementInsertTo();
	global $log;

	if(!array_key_exists('data', $tos))
		return;

	try {
		//binds values generic for all to
		$stmt->bindValue(':refer', $refer, PDO::PARAM_STR);

		foreach($tos['data'] as $to ){
			if(!array_key_exists('category', $to)){
				$log->info('to user '. $to['id']);
				if(!DBManager::existUser($to['id'])){

					$log->info('dump public profile from to[id]');
					dumpUserPublicProfile($to['id']);
				}
				$stmt->bindValue(':category', 'user', PDO::PARAM_STR);
			}
			else{

				$log->info('to category '. $to['category']);
				$stmt->bindValue(':category', $to['category'], PDO::PARAM_STR);
			}

			$stmt->bindValue(':to', $to['id'], PDO::PARAM_STR);
			if(!array_key_exists('name', $to))
				$stmt->bindValue(':name', NULL, PDO::PARAM_STR);
			else
				$stmt->bindValue(':name', $to['name'], PDO::PARAM_STR);

			$stmt->execute();
		}
	}
	catch(PDOException $e){
		$error = new Error(
				$e->getMessage(),
				'dumping tos[cron.php]',
				$refer,
				Error::LVL_ERROR
				);
		$error->report();
		throw $e;
	}

	$log->info('to finished');
	$stmt->closeCursor();
}

/**
 * Dumps a user puoblic profile from Facebook.
 * @param id user facebook id
 * @throw PDOException if something wrong happens.
 */
function dumpUserPublicProfile($id){
	global $fb;	
	global $log;

	//	$log->info('---- dumping public profile for ' . $id . ' ----');
	try {
//		$request = $id.'?fields=name,first_name,last_name,username,gender,locale';
		$request = $id;

		$upp = $fb->api($request, 'GET');
	} catch(Exception $e){
		$log->info('*************error while dumping ' . $id);
		//		exit();
		$error = new Error(
				$e->getMessage(),
				'Facebook raises this exception while cron is requesting a public profile. Request : ' . $request,
				$id,
				Error::LVL_ERROR
				);
		$error->report();
		return;
	}
	$gender = array_key_exists('gender', $upp) ? $upp['gender'] : NULL;
	$name = array_key_exists('name', $upp) ? $upp['name'] : NULL;
	$first_name = array_key_exists('first_name', $upp) ? $upp['first_name'] : NULL;
	$last_name = array_key_exists('last_name', $upp) ? $upp['last_name'] : NULL;
	$username = array_key_exists('username', $upp) ? $upp['username'] : NULL;
	$locale = array_key_exists('locale', $upp) ? $upp['locale'] : NULL;
	DBManager::addUserPublicProfile($upp['id'], $name, $first_name, $last_name, $username, $gender, $locale);
}
?>
